package com.zszedu.service;


import com.zszedu.mapper.BigInfoMapper;
import com.zszedu.mapper.ProductMapper;
import com.zszedu.pojo.BidInfo;
import com.zszedu.pojo.Income;
import com.zszedu.pojo.Page;
import com.zszedu.pojo.Product;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.Date;
import java.util.List;


@DubboService
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private BigInfoMapper bigInfoMapper;
    @Autowired
    private IncomeService incomeService;

    public Double getAvgRate() {
       return productMapper.AvgRate();
    }

    //根据产品类型返回总数量
    @Override
    public Integer querySum(Integer type) {
        return productMapper.querySum(type);
    }

    //根据产品类型查询数据，从那个下标开始查询，返回的数量
    @Override
    public List PageData(Integer type, Integer start, Integer pageSize) {
        return productMapper.PageData(type, start, pageSize);
    }

    @Override
    public Product queryById(Integer id) {
        return productMapper.queryById(id);
    }

    //根据产品类型type以及产品期限cycle查询信息，只返回一个对象
    @Override
    public Product queryByTypeAndCycle(Integer type, Integer cycle) {
        return productMapper.queryByTypeAndCycle(type,cycle);
    }
    //根据产品类型(productType)/产品状态(productStatus)并且按照金额排序(从小到大)，返回固定的长度 limit
    @Override
    public List queryByTypeAndStatus(Integer type, Integer limit) {
        return productMapper.queryByTypeAndStatus(type, limit);
    }

    //分页器!!!!!!!!!!
    @Override
    public Page queryPage(Integer type, Integer currPage) {
        //每页显示的数量
        Integer pageSize = 9;

        //列如 60 条总数据，需要每页显示10条数据    60-1 / 10+1
        //总页数的计算工具 (总数据数-1 除以 每页面数据数+1 )
        /* 数据库的计算 (参数一:下标，参数二:显示的数据数量)
            limit start,length
            select * from xx limit 0,10  第1页
            select * from xx limit 10,10  第2页
            select * from xx limit 20,10  第3页
            ...
            select * from xx limit (n-1)*10, 10  第n页
         */
        Page page = new Page();
        //根据产品类型获取数据总数，总数据长度 - 1 除以 每页面数据数+1
        Integer totalCount = productMapper.querySum(type);
        Integer totalPage = (totalCount - 1) / pageSize + 1;

        //从数据库中查询当前页面显示的数据根据数据库的条件，start=指定下标开始往后返回数据
        //获取当前页中需要显示的数据下标从几开始(第一页为从0开始)
        Integer start = (currPage-1) * pageSize;
        List list = productMapper.PageData(type, start, pageSize);

        // 当前页数据
        page.setTotalPage(totalPage);
        page.setData(list);

        return page;
    }

    //查询满标产品
    @Override
    public List<Product> queryFullProduct() {
        return productMapper.queryFullProduct();
    }


    //每天 12 点执行，扫描是否存在满标产品，产生收益计划
    @Transactional
    @Scheduled(cron = "0 0 12 ? * *")
    public void scanFullProduct(){
        System.out.println("开始运行");
        //查询所有满标产品
        List<Product> products = queryFullProduct();
        //如果为空则则直接结束
        if (products == null || products.size() == 0){
            return;
        }
        //遍历获取到的所有满标产品
        for (Product product : products) {
            //根据满标产品id，查询每个满标产品的所有投资记录
            List<BidInfo> bidInfos = bigInfoMapper.queryByPid(product.getId());
            //遍历计算收益金额添加到收益表中
            for (BidInfo bidInfo : bidInfos) {
                //计算收益金额: 投资金额 * 年利率 / 100(因为是百分比) / 12(算出一个月) * 产品期限(cycle)
                Double money = bidInfo.getBidMoney() * product.getRate() / 100 / 12 * product.getCycle();
                //计算收益时间:满标时间(2022-05-10) + 产品期限(1~12个月)
                Calendar instance = Calendar.getInstance();//JAVA日历对象(精准的获取当前年份的每个月天数)
                instance.setTime(product.getProductFullTime());//将时间设置为指定时间
                //1则代表的是对年份操作
                //2是对月份操作
                //3是对星期操作
                //5是对日期操作
                //11是对小时操作
                //12是对分钟操作
                //13是对秒操作
                //14是对毫秒操作
                instance.add(Calendar.MONTH,product.getCycle());//在月上加上指定的数值
                Date time = instance.getTime();//转换成日期对象

                //创建收益记录
                Income income = new Income();
                income.setUid(bidInfo.getUid());//用户id
                income.setProdId(product.getId());//产品id
                income.setBidId(bidInfo.getId());//投资记录id
                income.setBidMoney(bidInfo.getBidMoney());//投资金额
                income.setIncomeMoney(money);//收益金额
                income.setIncomeDate(time);//收益到账时间
                income.setIncomeStatus(0);//收益状态(0:未返回 / 1:已返回)

                //添加进入数据库中
                incomeService.addIncome(income);
            }
            //修改产品状态为2:满标已生成收益计划
            productMapper.editStatusAndTime(Math.toIntExact(product.getId()),2,new Date());
        }
        System.out.println("运行完毕");
    }

}
